package guava;

import com.google.common.util.concurrent.*;
import org.junit.Before;
import org.junit.Test;

import java.io.FileNotFoundException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

/**
 * Futures：用于处理Future实例的工具类
 * User: Realfighter
 * Date: 2014/11/16
 * Time: 16:56
 */
public class FuturesTest {

    private ExecutorService executor;
    private ListeningExecutorService executorService;
    private ListenableFuture<String> listenableFuture;
    private Person person;

    @Before
    public void setUp() {
        executor = Executors.newCachedThreadPool();
        executorService = MoreExecutors.listeningDecorator(executor);
        person = new Person();
    }

    @Test
    public void testFuturesTransform() throws ExecutionException, InterruptedException {
        listenableFuture = executorService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "张三";
            }
        });
        AsyncFunction<String, Person> asyncFunction = new AsyncFunction<String, Person>() {
            @Override
            public ListenableFuture<Person> apply(String input) throws Exception {
                person.setName(input);
                return executorService.submit(new Callable<Person>() {
                    @Override
                    public Person call() throws Exception {
                        return person;
                    }
                });
            }
        };
        ListenableFuture<Person> lf =
                Futures.transform(listenableFuture, asyncFunction);
        assertThat(lf.get().getName(), is("张三"));
    }

    @Test
    public void testFuturesFallback() throws ExecutionException, InterruptedException {
        listenableFuture = executorService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                throw new RuntimeException();
            }
        });
        FutureFallback<String> futureFallback = new FutureFallback<String>() {
            @Override
            public ListenableFuture create(Throwable t) throws Exception {
                if (t instanceof RuntimeException) {
                    SettableFuture<String> settableFuture =
                            SettableFuture.create();
                    settableFuture.set("Not Found");
                    return settableFuture;
                }
                throw new Exception(t);
            }
        };
        ListenableFuture<String> lf =
                Futures.withFallback(listenableFuture,futureFallback);
        assertThat(lf.get(), is("Not Found"));
    }

    class Person {
        int age;
        String name;

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
